﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.Xna.Framework.Content.Pipeline;
using Tomahawk.Serialization.Reflection;
using System.Reflection;
using System.Xml.Serialization;
using Tomahawk.Serialization.SerialBoost;
using System.Xml;

namespace Tomahawk.Processors
{
    [ContentImporter(".xml", DefaultProcessor = "", DisplayName = "XML Archetype Importer - Tomahawk Engine")]
    class ArchetypeImporter : ContentImporter<MemoryStream>
    {
        public override MemoryStream Import(string filename, ContentImporterContext context)
        {
            MemoryStream retVal = new MemoryStream();

            this.loadAssemblies(context.OutputDirectory);

            //read the input file into a string
            string xmlString = System.IO.File.ReadAllText(filename, Encoding.UTF8);

            //get the short type name
            int firstClose = xmlString.IndexOf('>');
            int beginElement = xmlString.IndexOf('<', firstClose);
            int endElement = xmlString.IndexOf(' ', beginElement);
            string sType = xmlString.Substring(beginElement + 1, (endElement - beginElement) - 1);

            //get the full type name
            int firstAtt = xmlString.IndexOf("type=", endElement);
            int endAtt = xmlString.IndexOf("\"", firstAtt + 6);
            string tType = xmlString.Substring(firstAtt + 1, (endAtt - firstAtt) - 1);

            //get the actual type
            Type targetType = this.searchTypeByName(tType);

            //instance an object of this type
            object targetObject = null;
            if (targetType != null)
            {
                XmlSerializer xmlS = new XmlSerializer(targetType);
                FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
                targetObject = xmlS.Deserialize(fs);
            }

            //TODO: Get a BoostSerialize and save serialize to stream
            IBoostSerializer bs = null;
            XmlWriter xmlW = XmlWriter.Create(retVal);
            bs.Serialize(targetObject, xmlW);

            //rewind the stream
            retVal.Seek(0, SeekOrigin.Begin);

            //return
            return retVal;
        }

        Assembly[] assemblyList;

        private void loadAssemblies(string appPath)
        {
            System.IO.DirectoryInfo dirInfo = new DirectoryInfo(appPath);
            FileInfo[] files = dirInfo.GetFiles("*.exe");
            this.assemblyList = new Assembly[files.Length];
            int cnt = 0;
            foreach (FileInfo fi in files)
            {
                this.assemblyList[cnt] = Assembly.LoadFile(fi.FullName);
            }
        }

        private Type searchTypeByName(string typeName)
        {
            Type retVal = null;
            for (int i = 0; i<this.assemblyList.Length; i++) 
            {
                Assembly currentAsm = this.assemblyList[i];
                if (currentAsm != null)
                {
                    try
                    {
                        Type[] typeList = currentAsm.GetTypes();
                        for (int j = 0; j < typeList.Length; j++)
                        {
                            Type currentType = typeList[j];
                            if (currentType.FullName == typeName) retVal = currentType;
                        }
                    }
                    catch (Exception) { }
                }
            }
            return retVal;
        }

    }

}
